package com.nhutcm.sms.activity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.Toast;

import com.nhutcm.sms.Callback.DataRequestCallback;
import com.nhutcm.sms.Utils.AppApplication;
import com.nhutcm.sms.Utils.Constant;
import com.nhutcm.sms.Utils.JsonParserUtils;
import com.nhutcm.sms.Utils.LogUtils;
import com.nhutcm.sms.Utils.LogUtils.Level;
import com.nhutcm.sms.Utils.PrefUtils;
import com.nhutcm.sms.Utils.StringUtils;
import com.nhutcm.sms.model.SMSClass;
import com.nhutcm.sms.network.SMSBroadcastingNetwork;
import com.nhutcm.sms.receiver.SMSBroadcastingReceiver;
import com.nhutcm.smsbroadcasting.R;

public class MainActivity extends ActionBarActivity implements
		DataRequestCallback {

	public static final String KEY_DELAY_SEND_REQ = "delay_send_req";
	public static final String KEY_DELAY_SEND_SMS = "delay_send_sms";
	public static final String KEY_TOKEN = "token";
	private static boolean isUsingTimer = true;

	public static String TAG = "MainActivity";
	List<String> lstSMS = new ArrayList<String>();
	Context mContext;
	Timer timer = null;

	String timeDelaySendReq, timeDelaySendSMS, token;

	HashMap<String, String> hashmap = null;
	List<String> lsKey = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		loadConfig(this);

		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);

		setContentView(R.layout.activity_main);
		getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
		AppApplication.getInstance(this).setCurrentCtx(MainActivity.this);
		mContext = this;

		if (savedInstanceState == null) {
			getSupportFragmentManager().beginTransaction()
					.add(R.id.container, new PlaceholderFragment()).commit();
		}
		LogUtils.write(Level.INFO, "onCreate");
		timer = AppApplication.getInstance(this).getTimer();
		if (timer == null) {
			createTimer(this);
		}

		// create hashmap for contain update value
		hashmap = new HashMap<String, String>();
		lsKey = new ArrayList<String>();

	}

	void loadConfig(Context context) {
		timeDelaySendReq = PrefUtils.readStringFromPreference(context,
				KEY_DELAY_SEND_REQ);
		timeDelaySendSMS = PrefUtils.readStringFromPreference(context,
				KEY_DELAY_SEND_SMS);
		token = PrefUtils.readStringFromPreference(context, KEY_TOKEN);

		if (timeDelaySendReq != null) {
			Constant.PERIUS_TIME_SEND_REQ = Integer.parseInt(timeDelaySendReq)
					* Constant.ONE_SECODE;
		}
		if (timeDelaySendSMS != null) {
			Constant.WAITING_SEND_SMS = Integer.parseInt(timeDelaySendSMS)
					* Constant.ONE_SECODE;
		}
		if (token != null) {
			Constant.TOKEN = token;
		}
	}

	void createTimer(Context context) {
		timer = new Timer();
		timer.scheduleAtFixedRate(new TimerTask() {
			public void run() {
				if (Constant.SERVER_ON && isUsingTimer) {
					SMSBroadcastingNetwork.sendGetListRequest(mContext);
					LogUtils.write(Level.INFO, "SEND REQUEST BY TIMER");
				}
			}
		}, Constant.ONE_SECODE, Constant.PERIUS_TIME_SEND_REQ);
		AppApplication.getInstance(context).setTimer(timer);
	}

	void resetTimer(Context context) {
		if (timer != null) {
			timer.cancel();
			timer = null;
		}
		createTimer(context);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			showDialog(this);
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	/**
	 * A placeholder fragment containing a simple view.
	 */
	public static class PlaceholderFragment extends Fragment {

		public PlaceholderFragment() {
		}

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {
			View rootView = inflater.inflate(R.layout.fragment_main, container,
					false);

			RelativeLayout layout = (RelativeLayout) rootView
					.findViewById(R.id.layout);
			if (Constant.SERVER_ON) {
				layout.setBackgroundResource(R.drawable.bg_on);
			} else {
				layout.setBackgroundResource(R.drawable.bg_off);
			}
			layout.setOnTouchListener(new OnTouchListener() {

				@Override
				public boolean onTouch(View v, MotionEvent event) {
					if (Constant.SERVER_ON) {
						v.setBackgroundResource(R.drawable.bg_off);
						Constant.SERVER_ON = false;
					} else {
						v.setBackgroundResource(R.drawable.bg_on);
						Constant.SERVER_ON = true;
					}

					return false;
				}
			});
			return rootView;
		}
	}

	@Override
	public void onGetListResult(String result) {
		List<SMSClass> list = JsonParserUtils.parseStringToObject(result);
		int size = list.size();
		if (size > 0) {
			isUsingTimer = false;
			for (int i = 0; i < size; i++) {
				SMSClass sms = list.get(i);
				if (sms.getMessage().length() <= Constant.MAX_NUM_CHARS_PER_MESSAGE) {
					SMSBroadcastingNetwork.sendSMS(mContext, sms);
				} else {
					SMSBroadcastingNetwork.sendLongSMS(mContext, sms);
				}
			}

			/** Diem xac dinh ket thuc 1 phien gui tin nhan */
			SMSBroadcastingNetwork.sendPointMessage(mContext);
		} else {
			isUsingTimer = true;
		}

	}

	@Override
	public void onSMSResultCallback(SMSClass sms) {
		// SMSBroadcastingNetwork.updateStatus(mContext, sms);
		String key = StringUtils.EncodeBase64(sms.getPhone() + "_"
				+ sms.getSmsno());
		if (key == null) {
			LogUtils.write(Level.ERROR, "ENCODE FAILS");
			return;
		}

		if (hashmap.containsKey(key)) {
			String status = sms.getStatus();
			if (status.equals(SMSBroadcastingReceiver.FAILS)) {
				hashmap.put(key, status);
			}
		} else {
			hashmap.put(key, sms.getStatus());
			lsKey.add(key);
		}
	}

	void showDialog(final Context context) {

		LayoutInflater li = LayoutInflater.from(context);
		View promptsView = li.inflate(R.layout.dialog, null);

		AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
				context);

		alertDialogBuilder.setView(promptsView);

		final EditText txtTimeDelayReq = (EditText) promptsView
				.findViewById(R.id.txtTimeDelayReq);

		final EditText txtTimeDelaySendSMS = (EditText) promptsView
				.findViewById(R.id.txtTimeDelaySendMessage);

		final EditText txtToken = (EditText) promptsView
				.findViewById(R.id.txtToken);

		if (timeDelaySendReq != null) {
			txtTimeDelayReq.setText(timeDelaySendReq);
		} else {// default
			txtTimeDelayReq.setText(String
					.valueOf(Constant.PERIUS_TIME_SEND_REQ
							/ Constant.ONE_SECODE));
		}
		if (timeDelaySendSMS != null) {
			txtTimeDelaySendSMS.setText(timeDelaySendSMS);
		} else {
			txtTimeDelaySendSMS.setText(String
					.valueOf(Constant.WAITING_SEND_SMS / Constant.ONE_SECODE));
		}

		if (token != null) {
			txtToken.setText(token);
		} else {
			txtToken.setText(Constant.TOKEN);
		}

		alertDialogBuilder
				.setCancelable(false)
				.setPositiveButton("OK", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int id) {

						String t_delay_send_req = txtTimeDelayReq.getText()
								.toString();

						String t_delay_send_sms = txtTimeDelaySendSMS.getText()
								.toString();

						String t_token = txtToken.getText().toString();

						// data != empty
						if (t_delay_send_req.equals("")
								|| t_delay_send_sms.equals("")
								|| t_token.equals("")) {
							Toast.makeText(mContext,
									"Config fails. Value is empty",
									Toast.LENGTH_SHORT).show();
							return;
						}

						// data must be > 5
						int t1 = Integer.parseInt(t_delay_send_req);
						int t2 = Integer.parseInt(t_delay_send_sms);
						if (t1 < 5 || t2 < 5) {
							Toast.makeText(mContext, "Value must be > 5s",
									Toast.LENGTH_SHORT).show();
							return;
						}

						// saving to share pref
						PrefUtils.saveStringToPreference(mContext,
								KEY_DELAY_SEND_REQ, t_delay_send_req);

						PrefUtils.saveStringToPreference(mContext,
								KEY_DELAY_SEND_SMS, t_delay_send_sms);

						PrefUtils.saveStringToPreference(mContext, KEY_TOKEN,
								t_token);

						loadConfig(context);

						// reset timer
						resetTimer(mContext);

					}
				})
				.setNegativeButton("Cancel",
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) {
								dialog.cancel();
							}
						});

		AlertDialog alertDialog = alertDialogBuilder.create();

		alertDialog.show();
	}

	@Override
	public void onPointCallback() {
		if (Constant.SERVER_ON) {

			/**
			 * Doan code cap nhat trang thai ben duoi con rat buoi, vi ko co
			 * thoi gian nhieu
			 */
			// gui cap nhat tinh trang
			int size = hashmap.size();
			if (size != lsKey.size()) {
				LogUtils.write(Level.ERROR,
						"KICH THUOC HASHMAP KHONG BANG VOI KICH THUOC LIST KEY");
				return;
			}
			for (int i = 0; i < size; i++) {
				String key = lsKey.get(i);
				String status = hashmap.get(key);

				if (status == null || status == "") {
					LogUtils.write(Level.ERROR, "KEY NOT FOUND IN HASHMAP");
					return;
				}

				key = StringUtils.DecodeBase64(key);
				if (key == null) {
					LogUtils.write(Level.ERROR, "DECODE FAILS");
					return;
				}

				String[] arr = key.split("_");
				if (arr.length != 2) {
					LogUtils.write(Level.ERROR, "Split key fails");
					return;
				}

				SMSClass sms = new SMSClass(arr[0], arr[1], "");
				sms.setStatus(status);
				SMSBroadcastingNetwork.updateStatus(mContext, sms);
			}
			hashmap.clear();
			lsKey.clear();

			// lay ds moi
			LogUtils.write(Level.INFO, "SEND REQUEST WITHOUT TIMER");
			SMSBroadcastingNetwork.sendGetListRequest(mContext);
		} else {
			isUsingTimer = true;
		}
	}
}
